#include<iostream>
#include<unistd.h>
#include<cstdio>
#include<sys/types.h>
#include<sys/wait.h>

void PrintPending(sigset_t &pending)
{
    std::cout<<"current process, pid: "<<getpid()<<", pending: ";
    for(int signo=31; signo>=1;signo--)
    {
        //检查signo信号是否存在于pending集合中，调试时验证信号屏蔽状态
        if(sigismember(&pending,signo)) 
        {
            std::cout<<1;
        }
        else
        {
            std::cout<<0;
        }
    }
    std::cout<<"\n";
}

void handler(int signo)
{
    std::cout<<signo<<"号信号已递达!!!"<<std::endl;
    std::cout<<"------------------------------------"<<std::endl;
    sigset_t pending;
    sigpending(&pending);
    PrintPending(pending);
    std::cout<<"------------------------------------"<<std::endl;
}

int main()
{
    //0.捕捉2号信号
    signal(2,handler);            // 信号的自定义捕捉
    signal(2,SIG_IGN);            // 信号的忽略动作
    signal(2,SIG_DFL);            // 信号的默认动作

    //1.屏蔽2号信号
    sigset_t block_set,old_set;
    sigemptyset(&block_set);                  //清空位图
    sigemptyset(&old_set);                    //清空位图
    sigaddset(&block_set,SIGINT);             //把2号信号添加到block_set，此处仅修改block_set，并没有修改当前进程
    //1.1设置进入进程的block表中
    sigprocmask(SIG_BLOCK,&block_set,&old_set);    //完成对2号信号的屏蔽
    
    int cnt=15;
    while (true)
    {
        // 2.获取当前进程的pending表
        sigset_t pending;
        sigpending(&pending); //

        // 3.打印pending信号集
        PrintPending(pending);
        sleep(1);
        cnt--;
        
        // 4.解除对2号信号的屏蔽
        if (cnt==0)
        {
            std::cout<<" 解除对2号信号的屏蔽!!! "<<std::endl;
            sigprocmask(SIG_SETMASK,&old_set,&block_set);
        }
        sleep(1);
    }   
    return 0;
}

